/*
 * Copyright (c) 2025 Industrial Software Feature Database
 */
package com.comac.ins.bomt.controller;

import com.comac.ins.bomt.domain.bo.CopyStandardBomV2Request;
import com.comac.ins.bomt.domain.bo.GenerateStrengthBomV2Request;
import com.comac.ins.bomt.domain.bo.ModifyStrengthBomV2Request;
import com.comac.ins.bomt.domain.bo.OriginalBomDetailQuery;
import com.comac.ins.bomt.domain.vo.*;
import com.comac.ins.bomt.service.*;
import com.comac.ins.common.biz.domain.vo.BizEventInfoVo;
import com.comac.ins.common.biz.event.BizEventService;
import com.comac.ins.common.core.domain.R;
import com.comac.ins.common.biz.utils.BizAssertUtil;
import com.comac.ins.common.biz.annotations.Digest;
import com.comac.ins.common.json.utils.JsonUtils;
import com.comac.ins.common.mybatis.core.page.PageQuery;
import com.comac.ins.common.mybatis.core.page.TableDataInfo;
import com.comac.ins.common.satoken.utils.LoginHelper;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;


/**
 * BOM控制器V2
 *
 * @author zhanghongyi
 * @date 2024/8/1 14:33
 * @description BomController
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/biz/bom-v2")
public class BomControllerV2 {

    private final BomManageServiceV2 bomManageServiceV2;
    private final BomGenerateServiceV2 bomGenerateServiceV2;
    private final BomQueryServiceV2 bomQueryServiceV2;
    private final BomExportServiceV2 bomExportServiceV2;

    /**
     * 上传原始装机清单V2（异步）
     *
     * @param aircraftModel 机型
     * @param desc          批次描述
     * @param track         批次号
     * @param groupType     分组类型
     * @param file          文件
     * @return 事件id列表
     */
    @PostMapping(value = "/upload/original", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @Digest(bizType = "biz-bom-upload-original-v2", logFields = {"aircraftModel", "desc","track","groupType","file?.getOriginalFilename()"})
    public R<List<Long>> uploadOriginal(
        @NotBlank(message = "机型不能为空") @RequestPart(value = "aircraftModel") String aircraftModel,
        @NotBlank(message = "批次描述不能为空") @RequestPart(value = "desc") String desc,
        @NotBlank(message = "批次号不能为空")  @RequestPart(value = "track") String track,
         @RequestPart(value = "groupType",required = false) String groupType,
        @NotNull(message = "上传文件不能为空") @RequestPart("file") MultipartFile file
    ) {
        BizAssertUtil.notNull(file.getOriginalFilename(), "file name empty");
        BizAssertUtil.isTrue(file.getOriginalFilename().endsWith(".xlsx"), "please use xlsx to init");
        Long eventInfoId = bomManageServiceV2.beginUploadOriginalBom(LoginHelper.getLoginUser(), file, aircraftModel, desc, track, groupType);
        return R.ok(Collections.singletonList(eventInfoId));
    }


    /**
     * 分页查询原始装机清单列表V2
     *
     * @param aircraftModel 机型
     * @param track         批次（可选）
     * @param pageQuery     分页参数
     * @return 原始装机清单文件列表
     */
    @GetMapping("/list/original")
    public TableDataInfo<OriginalBomV2InfoVo> listOriginal(
        @NotBlank(message = "机型不能为空")  String aircraftModel,
        @RequestParam(required = false) String track,
        PageQuery pageQuery
    ) {
        assignPageQueryDefaultOrderBy(pageQuery);
        return bomQueryServiceV2.listOriginalByPage(LoginHelper.getLoginUser(), aircraftModel, track,pageQuery);
    }

    /**
     * 查询原始装机清单信息V2
     *
     * @param id id
     * @return 原始装机清单文件列表
     */
    @GetMapping("/info/original")
    public OriginalBomV2InfoVo infoOriginal(
        @NotNull(message = "id不能为空")  Long id
    ) {
        return bomQueryServiceV2.queryOriginalBomInfoVoById(LoginHelper.getLoginUser(), id);
    }


    /**
     * 上传初始化记录V2（异步）
     *
     * @param aircraftModel 机型
     * @param desc          描述
     * @param track         批次号
     * @param file          文件（包含初始化标准装机清单和强度数模清单的Zip文件）
     * @return 事件id列表
     */
    @PostMapping(value = "/upload/init", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @Digest(bizType = "biz-bom-upload-init-v2", logFields = {"aircraftModel", "desc","track","file?.getOriginalFilename()"})
    public R<List<Long>> uploadInit(
        @NotBlank(message = "机型不能为空") @RequestPart(value = "aircraftModel") String aircraftModel,
        @NotBlank(message = "批次描述不能为空") @RequestPart(value = "desc") String desc,
        @NotBlank(message = "批次号不能为空")  @RequestPart(value = "track") String track,
        @NotNull(message = "上传文件不能为空") @RequestPart("file") MultipartFile file
    ) {
        BizAssertUtil.notNull(file.getOriginalFilename(), "file name empty");
        BizAssertUtil.isTrue(file.getOriginalFilename().endsWith(".zip"), "please use zip package file like C919_S11_标准装机清单.xlsx and C919_S11_强度数模清单.xlsx to init");
        Long eventInfoId = bomManageServiceV2.beginUploadInit(LoginHelper.getLoginUser(), file, aircraftModel, desc, track);
        return R.ok(Collections.singletonList(eventInfoId));
    }

    /**
     * 分页查询标准装机清单列表V2
     *
     * @param aircraftModel 机型
     * @param track         批次号
     * @param pageQuery     分页参数
     * @param section       部段（可选）
     * @param mainSection   主部段（可选）
     * @return 标准装机清单文件列表
     */
    @GetMapping("/list/standard")
    public TableDataInfo<StandardBomV2InfoVo> listStandard(
        @NotBlank(message = "机型不能为空")  String aircraftModel,
        @NotBlank(message = "批次不能为空") String track,
        @RequestParam(required = false) String section,
        @RequestParam(required = false) String mainSection,
        PageQuery pageQuery
    ) {
        assignPageQueryDefaultOrderBy(pageQuery);
        return bomQueryServiceV2.listStandardByPage(LoginHelper.getLoginUser(), aircraftModel,track,section,mainSection, pageQuery);
    }

    /**
     * 导出标准装机清单V2
     *
     * @param aircraftModel 机型
     * @param id          Bom id
     */
    @PostMapping("/export/standard")
    @Digest(bizType = "export-standard-v2", logFields = {"aircraftModel", "id"})
    public void exportStandard(
        @NotBlank(message = "机型不能为空") String aircraftModel,
        @NotNull(message = "Bom Id不能为空") Long id,
        HttpServletResponse response
    ) {
        bomExportServiceV2.exportStandardBom(LoginHelper.getLoginUser(), id, response);
    }
    /**
     * 导出强度数模清单V2
     *
     * @param aircraftModel 机型
     * @param id          Bom id
     */
    @PostMapping("/export/strength")
    @Digest(bizType = "export-strength-v2", logFields = {"aircraftModel", "id"})
    public void exportStrength(
        @NotBlank(message = "机型不能为空") String aircraftModel,
        @NotNull(message = "Bom Id不能为空") Long id,
        HttpServletResponse response
    ) {
        bomExportServiceV2.exportStrengthBom(LoginHelper.getLoginUser(), id, response);
    }

    /**
     * 导出对比强度数模清单结果V2
     *
     * @param leftAircraftModel 左机型
     * @param leftTrack  左批次号
     * @param leftGroupType 右分组类型
     * @param rightAircraftModel 右机型
     * @param rightTrack 右批次号
     * @param rightGroupType 右分组类型
     * @param response 导出
     */
    @PostMapping("/export/strengthCompare")
    @Digest(bizType = "export-strengthCompare-v2", logFields = {"leftAircraftModel", "leftTrack","leftGroupType","rightAircraftModel", "rightTrack","rightGroupType"})
    public void exportStrengthCompare(
        @RequestParam("leftAircraftModel")   @NotBlank(message = "左机型不能为空") String leftAircraftModel,
        @RequestParam("leftTrack")  @NotNull(message = "左批次号不能为空")  String leftTrack,
        @RequestParam("leftGroupType") @NotBlank(message = "左分组类型不能为空") String leftGroupType,
        @RequestParam("rightAircraftModel")   @NotBlank(message = "右机型不能为空") String rightAircraftModel,
        @RequestParam("rightTrack")  @NotNull(message = "右批次号不能为空")  String rightTrack,
        @RequestParam("rightGroupType") @NotBlank(message = "右组类型不能为空") String rightGroupType,
        HttpServletResponse response
    ) {
        bomExportServiceV2.exportStrengthCompare(LoginHelper.getLoginUser(), leftAircraftModel, leftTrack,leftGroupType, rightAircraftModel, rightTrack, rightGroupType, response);
    }

    /**
     * 分页查询强度数模清单列表V2
     *
     * @param aircraftModel 机型
     * @param track 批次号
     * @param pageQuery     分页参数
     * @param section       部段（可选）
     * @param mainSection   主部段（可选）
     * @return 标准装机清单文件列表
     */
    @GetMapping("/list/strength")
    public TableDataInfo<StrengthBomV2InfoVo> listStrength(
        @NotBlank(message = "机型不能为空")  String aircraftModel,
        @NotBlank(message = "批次不能为空") String track,
        @RequestParam(required = false) String section,
        @RequestParam(required = false) String mainSection,
        PageQuery pageQuery
    ) {
        assignPageQueryDefaultOrderBy(pageQuery);
        return bomQueryServiceV2.listStrengthByPage(LoginHelper.getLoginUser(), aircraftModel,track,section,mainSection, pageQuery);
    }

    /**
     * 查询所有批次号信息V2
     *
     * @param aircraftModel 机型(可选)
     * @return 原始装机清单文件列表
     */
    @GetMapping("/list/all-track-info")
    public List<AircraftTrackInfoVo> listAllTrackInfo(
        @RequestParam(required = false) String aircraftModel
    ) {
        Map<String, List<TrackGroupInfoVo>> infos = bomQueryServiceV2.listAllTrackInfo(LoginHelper.getLoginUser(), aircraftModel);
        List<AircraftTrackInfoVo> result = new ArrayList<>();
        for(Map.Entry<String, List<TrackGroupInfoVo>> entry:infos.entrySet()){
            AircraftTrackInfoVo aircraftTrackInfo= new AircraftTrackInfoVo();
            aircraftTrackInfo.setAircraftModel(entry.getKey());
            aircraftTrackInfo.setTrackGroupInfoVos(entry.getValue());
            result.add(aircraftTrackInfo);
        }
        return result;
    }


    /**
     * 生成标准装机清单V2（异步）
     *
     * @param aircraftModel 机型
     * @param originalBomId 原始装机清单Id
     * @return 事件id列表
     */
    @PostMapping("/generate/standard")
    @Digest(bizType = "standard-bom-generate-v2", logFields = {"aircraftModel", "originalBomId"})
    public R<List<Long>> generateStandard(
        @RequestParam("aircraftModel") @NotBlank(message = "机型不能为空") String aircraftModel,
        @RequestParam("originalBomId") @NotNull(message = "原始装机清单Id不能为null")  Long originalBomId
    ) {
        Long eventInfoId = bomGenerateServiceV2.beginGenerateStandard(LoginHelper.getLoginUser(), aircraftModel, originalBomId);
        return R.ok(Collections.singletonList(eventInfoId));
    }

    /**
     * 生成强度数模清单V2（异步）
     *
     * @param request 请求
     * @return 事件id列表
     */
    @PostMapping("/generate/strength")
    @Digest(bizType = "strength-bom-generate-v2", logFields = {"request?.aircraftModel", "T(org.apache.commons.lang3.StringUtils).join(request?.standardBomIds,',')"})
    public R<List<Long>> generateStrength(
        @RequestBody @Validated GenerateStrengthBomV2Request request
    ) {
        List<Long> eventInfoIds = bomGenerateServiceV2.beginGenerateStrength(LoginHelper.getLoginUser(), request.getAircraftModel(), request.getStandardBomIds(),request.getSectionCodeNames());

        return R.ok(eventInfoIds);
    }

    /**
     * 对比强度数模清单V2
     *
     * @param leftAircraftModel 左机型
     * @param leftTrack  左批次号
     * @param leftGroupType 左分组类型
     * @param rightAircraftModel 右机型
     * @param rightTrack 右批次号
     * @param rightGroupType 右分组类型

     */
    @PostMapping("/compare/strength")
    @Digest(bizType = "strength-bom-compare-v2", logFields = {"leftAircraftModel", "leftTrack","leftGroupType","rightAircraftModel","rightTrack","rightGroupType"})
    public R<StrengthBomChangeV2InfoVo> compareStrength(
        @RequestParam("leftAircraftModel")   @NotBlank(message = "左机型不能为空") String leftAircraftModel,
        @RequestParam("leftTrack")  @NotNull(message = "左批次号不能为空")  String leftTrack,
        @RequestParam("leftGroupType") @NotBlank(message = "左分组类型不能为空") String leftGroupType,
        @RequestParam("rightAircraftModel")   @NotBlank(message = "右机型不能为空") String rightAircraftModel,
        @RequestParam("rightTrack")  @NotNull(message = "右批次号不能为空")  String rightTrack,
        @RequestParam("rightGroupType") @NotBlank(message = "右分组类型不能为空") String rightGroupType
    ) {
        Long eventInfoId = bomGenerateServiceV2.beginCompareStrength(LoginHelper.getLoginUser(), leftAircraftModel, leftTrack, leftGroupType, rightAircraftModel, rightTrack, rightGroupType, false);
        BizEventInfoVo eventInfo = BizEventService.queryEventInfoById(eventInfoId);
        BizAssertUtil.notNull(eventInfo,"eventInfo not found");
        BizAssertUtil.notBlank(eventInfo.getReturnResult(),"eventInfo.return result is null");
        StrengthBomChangeV2InfoVo compareResult = JsonUtils.parseObject(eventInfo.getReturnResult(), StrengthBomChangeV2InfoVo.class);
        BizAssertUtil.notNull(compareResult,"parsed compareResult is null");
        return R.ok(compareResult);
    }

    /**
     * 分页查询原始装机清单明细V2
     *
     * @param aircraftModel 机型
     * @param track         批次号
     * @param subTrack      子批次号
     * @param name          名称（可选）
     * @param level         层级（可选）
     * @param version       版次（可选）
     * @param code          编码（可选）
     * @param sectionName   部段名称（可选）
     * @return 明细信息
     */
    @GetMapping("/detail/original")
    public TableDataInfo<DetailOriginalV2BomVo> queryOriginalBomDetail(
        @NotBlank(message = "机型不能为空")  String aircraftModel,
        @NotBlank(message = "批次号不能为空") String track,
        @NotBlank(message = "子批次号不能为空") String subTrack,
        @RequestParam(required = false) String name,
        @RequestParam(required = false) String level,
        @RequestParam(required = false) String version,
        @RequestParam(required = false) String code,
        @RequestParam(required = false) String sectionName,
        PageQuery pageQuery
    ) {
        OriginalBomDetailQuery query = new OriginalBomDetailQuery();
        query.setAircraftModel(aircraftModel);
        query.setTrack(track);
        query.setSubTrack(subTrack);
        query.setName(name);
        query.setLevel(level);
        query.setVersion(version);
        query.setCode(code);
        query.setSectionName(sectionName);
        BeanUtils.copyProperties(pageQuery, query);
        return bomQueryServiceV2.queryOriginalDetailByPage(LoginHelper.getLoginUser(), query);
    }

    /**
     * 分页查询标准装机清单明细V2
     *
     * @param aircraftModel 机型
     * @param infoId        标准装机清单Id
     * @param name          名称（可选）
     * @param code          编码（可选）
     * @return 明细信息
     */
    @GetMapping("/detail/standard")
    public TableDataInfo<DetailStandardV2BomVo> queryStandardBomDetail(
        @NotBlank(message = "机型不能为空")  String aircraftModel,
        @NotNull(message = "标准装机清单Id不能为空") Long infoId,
        @RequestParam(required = false) String name,
        @RequestParam(required = false) String code,
        PageQuery pageQuery
    ) {
        return bomQueryServiceV2.queryStandardDetailByPage(LoginHelper.getLoginUser(), pageQuery,aircraftModel,infoId,name,code);
    }

    /**
     * 分页查询强度数模清单明细V2
     *
     * @param aircraftModel 机型
     * @param track         批次
     * @param name          名称（可选）
     * @param code          编码（可选）
     * @return 明细信息
     */
    @GetMapping("/detail/strength")
    public TableDataInfo<DetailStrengthV2BomVo> queryStrengthBomDetail(
        @NotBlank(message = "机型不能为空")  String aircraftModel,
        @NotBlank(message = "批次不能为空") String track,
        @NotBlank(message = "分组类型不能为空") String groupType,
        @RequestParam(required = false) String name,
        @RequestParam(required = false) String code,
        PageQuery pageQuery
    ) {
        return bomQueryServiceV2.queryStrengthDetailByPage(LoginHelper.getLoginUser(), pageQuery,aircraftModel,track,groupType,name,code);
    }

    /**
     * 删除原始装机清单明细V2
     *
     * @param ids           明细Id列表
     */
    @DeleteMapping("/delete/original/detail")
    @Digest(bizType = "biz-bom-detail-original-delete", logFields = {"T(org.apache.commons.lang3.StringUtils).join(ids,',')"})
    public R<Void> deleteOriginalBomDetail(
        @NotNull(message = "id列表") @RequestParam List<Long> ids) {
        bomManageServiceV2.deleteOriginalBomDetails(LoginHelper.getLoginUser(), ids);
        return R.ok("success");
    }

    /**
     * 删除原始装机清单信息V2
     *
     * @param ids           Id列表
     */
    @DeleteMapping("/delete/original/info")
    @Digest(bizType = "biz-bom-info-original-delete", logFields = {"T(org.apache.commons.lang3.StringUtils).join(ids,',')"})
    public R<Void> deleteOriginalBomInfo(
        @NotNull(message = "id列表") @RequestParam List<Long> ids) {
        bomManageServiceV2.deleteOriginalBomInfos(LoginHelper.getLoginUser(), ids);
        return R.ok("success");
    }
    /**
     * 修改原始装机清单明细V2
     *
     * @param requestVo           修改的明细
     */
    @PostMapping("/modify/original")
    @Digest(bizType = "biz-bom-original-modify", logFields = {"request?.id"})
    public R<Void> modifyOriginalBom(
        @RequestBody @Validated DetailOriginalV2BomVo requestVo) {
        bomManageServiceV2.modifyOriginalBom(LoginHelper.getLoginUser(), requestVo);
        return R.ok("success");
    }

    /**
     * 修改拷贝标准装机清单V2
     *
     * @param request 请求
     */
    @PostMapping("/copy/standard")
    @Digest(bizType = "biz-bom-standard-copy", logFields = {"request?.srcStandardBomId","T(org.apache.commons.lang3.StringUtils).join(request?.deleteDetailIds,',')","request?.desc"})
    public R<Void> copyStandardBom(
        @RequestBody @Validated CopyStandardBomV2Request request) {
        Long srcStandardBomId = request.getSrcStandardBomId();
        List<Long> deleteDetailIds = request.getDeleteDetailIds();
        List<DetailStandardV2BomVo> modifyDetails = request.getModifyDetails();
        String desc = request.getDesc();
        bomManageServiceV2.copyStandardBom(LoginHelper.getLoginUser(), srcStandardBomId,deleteDetailIds,modifyDetails,desc);
        return R.ok("success");
    }

    /**
     * 修改强度数模清单V2
     *
     * @param request 请求
     */
    @PostMapping("/modify/strength")
    @Digest(bizType = "biz-bom-strength-modify", logFields = {"request?.srcStandardBomId","T(org.apache.commons.lang3.StringUtils).join(request?.deleteDetailIds,',')","request?.desc"})
    public R<Void> modifyStrengthBom(
        @RequestBody @Validated ModifyStrengthBomV2Request request) {
        Long srcStrengthBomId = request.getSrcStrengthBomId();
        List<Long> deleteDetailIds = request.getDeleteDetailIds();
        List<DetailStrengthV2BomVo> modifyDetails = request.getModifyDetails();
        String desc = request.getDesc();
        bomManageServiceV2.modifyStrengthBom(LoginHelper.getLoginUser(), srcStrengthBomId,deleteDetailIds,modifyDetails,desc);
        return R.ok("success");
    }


    /**
     * 默认分页按更新时间倒序排序
     *
     * @param pageQuery 分页查询
     */
    private void assignPageQueryDefaultOrderBy(PageQuery pageQuery) {
        if (StringUtils.isBlank(pageQuery.getOrderByColumn())) {
            pageQuery.setOrderByColumn("update_time");
        }
        if (StringUtils.isBlank(pageQuery.getIsAsc())) {
            pageQuery.setIsAsc("desc");
        }
    }
}
